package com.neusoft.hifly.netty.websocket.handler;

import org.apache.commons.lang3.StringUtils;
import org.springframework.kafka.core.KafkaTemplate;

import com.neusoft.hifly.core.log.Log;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;

/**
 * 处理消息的handler TextWebSocketFrame： 在netty中，是用于为websocket专门处理文本的对象，frame是消息的载体 这里已经指定了类型 如果这里是Object
 * 那么下面还需判断是不是TextWebSocketFrame类型
 */
public class WebSocketChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
	// kafka
	private KafkaTemplate<String, Object> kafkaTemplate;

	public WebSocketChatHandler(KafkaTemplate<String, Object> kafkaTemplate) {
		super();
		this.kafkaTemplate = kafkaTemplate;
	}

	// 用于记录和管理所有客户端的channle
	private static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
		// 获取客户端传输过来的消息
		final String content = StringUtils.trimToEmpty(msg.text());
		Log.info("WebSocket接收到的数据：" + content);

		kafkaTemplate.send("micro-netty", content);

		// 给客户端发送消息
		writeAndFlush("您的WebSocket数据已发送到Kafka的micro-netty主题，你的消息为:" + content);

	}

	private void writeAndFlush(String content) {
		//    	for (Channel channel: clients) {
		//			channel.writeAndFlush(
		//				new TextWebSocketFrame(
		//						"[服务器在]" + LocalDateTime.now()
		//						+ "接受到消息, 消息为：" + content));
		//		}
		// 下面这个方法，和上面的for循环，一致   向客户端发送数据
		clients.writeAndFlush(new TextWebSocketFrame(content));
	}

	/**
	 * 当客户端连接服务端之后（打开连接） 获取客户端的channle，并且放到ChannelGroup中去进行管理
	 */
	@Override
	public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
		clients.add(ctx.channel());
		Log.info("WebSocket客户端建立新的连接，channle对应的长id为：" + ctx.channel().id().asLongText());
		//		Log.info("WebSocket客户端建立新的连接，channle对应的短id为：" + ctx.channel().id().asShortText());

		writeAndFlush("WebSocket服务连接成功！");
	}

	/**
	 * 客户端断开
	 */
	@Override
	public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
		// 当触发handlerRemoved，ChannelGroup会自动移除对应客户端的channel,所以下面的remove不用我们再手写
		//		clients.remove(ctx.channel());
		Log.info("WebSocket客户端断开，channle对应的长id为：" + ctx.channel().id().asLongText());
		//		Log.info("WebSocket客户端断开，channle对应的短id为：" + ctx.channel().id().asShortText());
	}
}